/**
 * @file List.c
 * @brief Routines for manipulating lists of edges
 * @author Matt Stallmann @date 29 Dec 2001
 * $Id: List.c 10 2007-06-28 20:08:57Z mfms $
 */

/*
 *  Copyright (C) 1989, 2001, 2007  Matthias Stallmann, Prashant Hebbar.
 *  Contact: matt_stallmann@ncsu.edu
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program (file COPYING.txt); if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 *  USA.
 */

#include "All.h"

struct head_node {
  L_NODE * my_first;
  L_NODE * my_last;
};

struct list_node {
  EJ_NODE * my_edge;
  L_NODE * my_link;
};

H_NODE * new_list( void )
{
  H_NODE * L = (H_NODE *) malloc( sizeof( H_NODE ) );
  L->my_first = L->my_last = NULL;
  return L;
}

edge add_to_list( EJ_NODE * edge_ptr, H_NODE * L )
{
  edge new_node = (L_NODE *) malloc( sizeof( L_NODE ) );
  if( edge_ptr == NULL ) {
    fprintf( stderr, "\nError (add_to_list): NULL edge\n" );
    abort();
  }
  new_node->my_edge = edge_ptr;
  new_node->my_link = NULL;
  if( L->my_first == NULL ) {
    L->my_first = L->my_last = new_node;
  }
  else {
    L->my_last->my_link = new_node;
    L->my_last = new_node;
  }
  return new_node;
}

void remove_from_list( EJ_NODE * edge_ptr, H_NODE * L )
{
  L_NODE * previous = NULL;
  L_NODE * current = L->my_first;

  if( edge_ptr == NULL ) {
    fprintf( stderr, "\nError (remove_from_list): NULL edge\n" );
    abort();
  }

  while( IS_VALID_EJ( current ) && current->my_edge != edge_ptr ) {
    previous = current;
    current = current->my_link;
  }

  if ( ! IS_VALID_EJ( current ) ) {
	 fprintf(stderr,"\nError (remove_from_list): edge not found (%d,%d)\n",
				edge_ptr->my_first_vertex, edge_ptr->my_second_vertex );
	 abort();
  }

  /* bypass the edge on this list and deallocate the node */
  if( previous != NULL ) {
    previous->my_link = current->my_link;
  }
  else {
    L->my_first = current->my_link;
  }
  if( current == L->my_last ) L->my_last = previous;
  free( current );
}

edge first_on_list( H_NODE * L )
{
  if( ! IS_VALID_EJ( L->my_first ) ) {
    return NULL_EDGE;
  }
  else return L->my_first;
}

edge next_on_list( edge e )
{
  if( ! IS_VALID_EJ( e->my_link ) ) {
    return NULL_EDGE;
  }
  else return e->my_link;
}

EJ_NODE * get_edge_record( edge e )
{
  if( e == NULL_EDGE ) {
    fprintf( stderr, "\nError (get_edge_record): null edge\n" );
    abort();
  }
  else return e->my_edge;
}

int are_edges_equal( edge ej1, edge ej2 )
{
  if ( ej1 == NULL_EDGE && ej2 == NULL_EDGE )
	 return(TRUE);
  if ( ej1 == NULL_EDGE || ej2 == NULL_EDGE )
	 return(FALSE);
  if ( ! IS_VALID_EJ( ej1 ) || ! IS_VALID_EJ( ej2 ) ) {
    fprintf( stderr, "\nError (are_edges_equal): invalid edge\n" );
    abort();
  }
  if ( ej1->my_edge == ej2->my_edge )
	 return(TRUE);
  return(FALSE);
} /* are_edges_equal ends */

/** end of List.c **/

/*  [Last modified: 2007 06 28 at 19:22:02 GMT] */
